package com.qianniu.napi.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.qianniu.napi.admin.entity.Maccount;
import com.qianniu.napi.admin.entity.MaccountFlow;
import com.qianniu.napi.admin.entity.penum.IotypeEnum;
import com.qianniu.napi.admin.entity.penum.XftypeEnum;
import com.qianniu.napi.admin.mapper.MaccountFlowMapper;
import com.qianniu.napi.admin.mapper.MaccountMapper;
import com.qianniu.napi.admin.service.IMaccountFlowService;
import com.qianniu.napi.admin.service.IMaccountService;
import com.qianniu.napi.common.util.ObjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 商家账务表 服务实现类
 * </p>
 *
 * @author chenxuebin
 * @since 2018-08-08
 */
@Service
public class MaccountServiceImpl extends ServiceImpl<MaccountMapper, Maccount> implements IMaccountService {

    private final static Logger logger = LoggerFactory.getLogger(MaccountServiceImpl.class);

    @Autowired
    MaccountMapper maccountMapper;
    @Autowired
    MaccountFlowMapper maccountFlowMapper;
    @Autowired
    IMaccountFlowService maccountFlowService;

    public void addMamountFlow(Long mid, BigDecimal amount2, BigDecimal mamount,
                               Boolean isconfirm, BigDecimal jifen,
                               String sn, IotypeEnum iotype, Integer xftype, String remark, Long ywid,String transactionid) {

        if (mid == null) {
            logger.error("===================addMaccountFlow pass mid=null");
            return;
        }
        Maccount mact = maccountMapper.getMaccountBymid(mid);

        MaccountFlow mf = new MaccountFlow();
        // *******  客户消耗  *******
        mf.setAmount(amount2);
        mf.setMamount(mamount);
        mf.setSn(sn);// 抵扣积分时 = 订单号
        mf.setTransactionid(transactionid);// 抵扣积分时 = 订单号
        mf.setIotype(iotype.getVal());//积分消费
        mf.setXftype(xftype);//积分消费
        mf.setJifen(jifen);
        mf.setCreatetime(new Date());
        mf.setMid(mid);
        mf.setUid(ObjectUtil.getUid());
        mf.setTradetime(new Date());
        mf.setCreatetime(mf.getTradetime());
        mf.setRemark(remark);
        mf.setIsConfirm(isconfirm ? 1 : -1);
        if (isconfirm) mf.setConfirmDate(new Date());
        if (isconfirm) mf.setLasttotal(mact.getTotal());
        mf.setState(1);
        mf.insert();

        int flag = 0;
        Maccount mbean = new Maccount();//更新Maccount
        while (flag == 0 && isconfirm) {

            Long version = mact.getVersion();
            if (amount2 != null && amount2.doubleValue() > 0) {
                BigDecimal total = mact.getTotal();
                BigDecimal amount = mact.getAmount();
                BigDecimal sale = mact.getSaleAmount();

                mbean.setTotal(iotype.getVal() == 1 ? total.add(amount2) : total.subtract(amount2));
                if (iotype.getVal() == 1) mbean.setSaleAmount(sale.add(amount2));
                mbean.setAmount(iotype.getVal() == 1 ? amount.add(amount2) : amount.subtract(amount2));
            }

            if (mamount != null && mamount.doubleValue() > 0) {
                BigDecimal mmount = mact.getAmount();
                mbean.setMamount(iotype.getVal() == 1 ? mmount.add(mamount) : mmount.subtract(mamount));
            }
            if (jifen != null && jifen.doubleValue() > 0) {
                BigDecimal jf = mact.getJifen();
                mbean.setJifen(iotype.getVal() == 1 ? jf.add(jifen) : jf.subtract(jifen));
            }

            mbean.setModifytime(new Date());
            mbean.setModifier(ObjectUtil.getUid());
            mbean.setVersion(version + 1);

            // ******* 更新账户表 ********
            flag = maccountMapper.update(mbean, new EntityWrapper<Maccount>().eq("mid", mid).eq("version", version));
            logger.debug(">>>>>>>>>>>>IMaccountService addMaccountFlow.update flag=" + flag);
            if (flag == 0) mact = maccountMapper.getMaccountBymid(mid);
        }
    }

    public Boolean maccountFlowConfirm(String sn, String transaction_id) {
        logger.info("----------------------------------------------------maccountFlowConfirm");
        logger.info("----------------------------------------------------maccountFlowConfirm");
        logger.info("----------------------------------------------------maccountFlowConfirm");
        logger.info("----------------------------------------------------maccountFlowConfirm");
        int cout = 0;
        MaccountFlow maf = maccountFlowService.selectOne(new EntityWrapper<MaccountFlow>().eq("sn", sn));
        Long mid = maf.getMid();
        if (maf != null) {
            Maccount nmaccount = null;
            Maccount ma = new Maccount();//更新maccountFlowConfirm
            while (cout == 0) {
                List<Maccount> maccounts = maccountMapper.selectList(new EntityWrapper<Maccount>().eq("mid", mid));
                if (maccounts == null || maccounts.size() == 0) {
                    logger.debug("----------------------------------------maccount at mid=" + mid + " not exist and sn=" + sn);
                    logger.debug("----------------------------------------start to init maccount");
                    ma = initMaccount(null,mid);
                } else {
                    ma = maccounts.get(0);
                }
                if (ma == null) {
                    break;
                }
                nmaccount = new Maccount();//更新maccountFlowConfirm

                maf.setTransactionid(transaction_id);
                maf.setIsConfirm(1);
                maf.setConfirmDate(new Date());

                Long version = ma.getVersion();
                BigDecimal amount = ma.getAmount();
                BigDecimal total = ma.getTotal();
                BigDecimal sale = ma.getSaleAmount();
                BigDecimal market = ma.getMamount();

                nmaccount.setTotal(maf.getIotype() == 1 ? maf.getAmount().add(total) : total.subtract(maf.getAmount()));       // 总金额
                if (maf.getIotype() == 1) nmaccount.setSaleAmount(maf.getAmount().add(sale));    //累计销售额度

                nmaccount.setAmount(maf.getIotype() == 1 ? maf.getAmount().add(amount) : amount.subtract(maf.getAmount()));    // 可用余额
                nmaccount.setMamount(maf.getIotype() == 1 ? maf.getMamount().add(market) : market.subtract(maf.getMamount())); // 营销总金额

                nmaccount.setModifytime(new Date());
                nmaccount.setVersion(version + 1);
                nmaccount.setMid(mid);

                cout = maccountMapper.update(nmaccount, new EntityWrapper<Maccount>().eq("id", ma.getId()).eq("version", version));
                logger.info("------------Account  cout=" + cout);
                if (cout > 0) maf.insertOrUpdate();
            }
        }

        return cout != 0;
    }

    public void addMaccountOutFlow(MaccountFlow maf) {

        Long uid = maf.getUid();
        Long mid = maf.getMid();
        Long mpid = maf.getMpid();

        Maccount entity = new Maccount();
        Maccount mact = new Maccount();
        entity.setMid(mid);
        Maccount account = maccountMapper.selectOne(entity);

        if (account == null) account = initMaccount(uid, mid);

        maf.insert();

        int ret = 0;
        Maccount mbean = new Maccount();
        BigDecimal money = maf.getAmount();

        while (ret == 0) {

            mact = maccountMapper.selectOne(entity);

            Long version = mact.getVersion();
            BigDecimal total = mact.getTotal();
            BigDecimal amount = mact.getAmount();

            // ******* 待完善 商户账户余额不足的情况处理 *********
            if (maf.getXftype() == XftypeEnum.withdraw.getVal()) {
                mbean.setTotal(total.subtract(money));
                mbean.setAmount(amount.subtract(money));
            }

            mbean.setModifytime(new Date());
            mbean.setModifier(uid);
            mbean.setVersion(version + 1);

            maf.setIsConfirm(1);
            maf.setLasttotal(mact.getTotal());
            maf.setConfirmDate(new Date());
            maf.setModifytime(new Date());

            // ******* 更新账户表 ********
            ret = maccountMapper.update(mbean, new EntityWrapper<Maccount>().eq("mid", mid).eq("version", version));
            logger.debug(">>>withdrawApply maccountService.update ret=" + ret);
            if (ret > 0) maf.insertOrUpdate();
        }
    }

    public Maccount initMaccount(Long uid, Long mid) {

        BigDecimal zero = new BigDecimal(0);

        Maccount act = new Maccount();//初始化Maccount()
        act.setUid(uid);
        act.setMid(mid);
        act.setCreatetime(new Date());
        act.setVersion(1l);
        act.setState(1);

        act.setTotal(zero);
        act.setAmount(zero);
        act.setSaleAmount(zero);
        act.setMamount(zero);
        act.setUnuseAmount(zero);
        act.setFanliing(zero);
        act.setFreeze(zero);
        act.setChargeAmount(zero);
        act.setWithdraw(zero);
        act.setConsume(zero);
        //sms
        act.setSmsmout(new BigDecimal("80"));
        act.setSmsmoutTotal(new BigDecimal("80"));
        act.setSmsprice(new BigDecimal("0.08"));
        act.setSmstotal(1000);
        act.insert();

        logger.info("========initMaccount=" + JSON.toJSONString(act));
        return act;
    }
}
